﻿using System;
using System.Collections.Generic;
using UnityEngine;
using Object = UnityEngine.Object;
namespace GxFramework 
{
    public class AbAssetRequest
    {
#region 回调注册/派发
        object _listeners;
        public bool AddListener(AssetDelegate del)
        {
            if (this.isDone)
            {
                del.Invoke(this);
                return true;
            }
            if (null == _listeners)
            {
                _listeners = del;
                return true;
            }

            List<AssetDelegate> list;
            if (_listeners is AssetDelegate)
            {
                if (del == (_listeners as AssetDelegate))
                    return false;
            }

            if (_listeners is List<AssetDelegate>)
                list = _listeners as List<AssetDelegate>;
            else
            {
                list = new List<AssetDelegate>();
                list.Add(_listeners as AssetDelegate);
            }
            if (list.Contains(del))
                return false;
            list.Add(del);
            return true;
        }
        public bool RemoveListener(AssetDelegate del)
        {
            if (_listeners is AssetDelegate)
            {
                if ((_listeners as AssetDelegate) == del)
                {
                    _listeners = null;
                    return true;
                }
            }
            else if (_listeners is List<AssetDelegate>)
            {
                var list = _listeners as List<AssetDelegate>;
                if (list.Remove(del))
                {
                    if (list.Count == 0)
                    {
                        _listeners = null;
                    }
                    return true;
                }
            }
            return false;

        }
        public void ClearListeners()
        {
            if (_listeners is List<AssetDelegate>)
            {
                var list = _listeners as List<AssetDelegate>;
                list.Clear();
            }
            _listeners = null;
        }
        public int listenerCount
        {
            get
            {
                if (null == _listeners)
                    return 0;
                if (_listeners is AssetDelegate)
                    return 1;
                return (_listeners as List<AssetDelegate>).Count;
            }
        }
        public void Invoke()
        {
            if (null == _listeners || !this.isDone)
                return;
            if (_listeners is AssetDelegate)
            {
                var del = (_listeners as AssetDelegate);
                del.Invoke(this);
                return;
            }
            var list = _listeners as List<AssetDelegate>;
            int len = list.Count;
            for (int i = 0; i < len; ++i)
            {
                list[i].Invoke(this);
            }
        }
#endregion

        AssetBundleInfo _abInfo;

        string _name;
        Type _type;

        AssetBundleRequest _abRequest;
        Object _asset;

        public string path { get { return _abInfo.path; } }
        public string assetName { get { return _name; } }
        public Type assetType
        {
            get
            {
                var obj = this.asset;
                if (null != obj)
                    return obj.GetType();
                return _type;
            }
        }
        public Object[] allAssets { get { return _abInfo.allAssets; } }
        public Object asset
        {
            get
            {
                if (null == _asset)
                {
                    if (null != _abRequest && _abRequest.isDone)
                    {
                        _asset = _abRequest.asset;
                    }
                    if (null == _asset)
                    {
                        if (null != _abInfo.allAssets && _abInfo.allAssets.Length == 1)
                            _asset = _abInfo.allAssets[0];
                    }
                }
                return _asset;
            }
        }
        
        public void Init(AssetBundleInfo assetInfo, string assetName, Type assetType)
        {
            _abInfo = assetInfo;
            _name = assetName;
            _type = assetType;
        }
        public bool IsMatch(string assetName, Type assetType)
        {
            if (!this.assetType.IsAssignableFrom(assetType))
                return false;
            if (_name != assetName)
                return false;
            return true;
        }
        public bool isDone 
        {
            get { return this.status == AssetLoadStatus.Success || this.status == AssetLoadStatus.Fail; }
        }
        public float progress
        {
            get
            {
                if (this.isDone)
                    return 1f;
                if (null == _name)
                    return _abInfo.progress;

                float v = 0.8f*0f;// _abInfo.progress;
                if (null != _abRequest)
                {
                    v += _abRequest.progress * 0.2f;
                }
                return v;
            }
        }
        public int status { get; private set; }
        public void Wait()
        {
            this.status = AssetLoadStatus.Wait;
        }
        public void Load()
        {
            this.status = AssetLoadStatus.Running;
            if(null != _name)
                _abRequest = _abInfo.assetBundle.LoadAssetAsync(_name, _type);
        }
        //启动加载后才会调用
        public void Update()
        {
            if (this.isDone)
                return;

            if(null == _name)
                this.status = AssetLoadStatus.Success;

            else if (null != _abRequest && _abRequest.isDone)
            {
                this.status = AssetLoadStatus.Success;
                _asset = _abRequest.asset;
                _abRequest = null;
            }
        }
        //取消下载：
        public void Unload()
        {
            this.status = AssetLoadStatus.Idle;
        }
    }
}